package com.qcby.chatservice.socket.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.qcby.chatservice.common.result.Result;
import com.qcby.chatservice.common.enums.ResponseStatus;
import com.qcby.chatservice.common.enums.SocketHandleType;
import com.qcby.chatservice.common.utils.SpringFactoryUtils;
import com.qcby.chatservice.socket.context.FlowContext;
import com.qcby.chatservice.socket.handle.ChatServiceHandle;
import com.qcby.chatservice.socket.service.IBaseChatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.tio.core.Tio;
import org.tio.websocket.common.WsResponse;

import java.util.Map;

/**
 * 聊天服务具体实现
 *
 * @author cong.zhen
 * @date 2023/01/07
 */
@Service
@Slf4j
@DependsOn("springFactoryUtils")
public class BaseChatServiceImpl implements IBaseChatService {

    Map<String, ChatServiceHandle> handleMap = SpringFactoryUtils.getBeanMap(ChatServiceHandle.class);


    @Override
    public void doAction(FlowContext context) {
        //获取事件
        String handleType = SocketHandleType.getHandleByCode(context.getHandleType());
        ChatServiceHandle handle = handleMap.get(handleType);

        try {
            //执行前置动作 校验，幂等，装配参数
            Result result = handle.beforeStateExecute(context);
            if(!result.isSuccess()){
                log.error("消息前置校验失败");
                Result<Object> error = Result.getBusinessException("前置校验失败", ResponseStatus.PARAM_ERROR_STATUS.getCode());
                sendToUser(error,context);
            }
            //状态执行动作 入库
            handle.doStateExecute(context);
            //状态执行后置动作 通知流转
            handle.afterStateExecute(context);
        }catch (Exception e){
            handle.rollBackExecute(context);
            log.error("flowException", e);
            Result<Object> error = Result.getBusinessException("业务异常", ResponseStatus.BUSINESS_ERROR_STATUS.getCode());
            sendToUser(error,context);
        }
    }

    /**
     * 发送给用户
     *
     * @param result  结果
     * @param context 上下文
     */
    public void sendToUser(Result result,FlowContext context){
        WsResponse wsResponse = WsResponse.fromText(JSONObject.toJSONString(result), "utf-8");
        Tio.sendToUser(context.getChannelContext().tioConfig,context.getOperateEmp(),wsResponse);
    }
}
